package com.baymax.custom.aspect;

import com.baymax.custom.annation.ExecutionTimeStatistics;
import com.baymax.custom.context.StopWatchContext;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.Map;

/**
 * ExecutionTimeStatisticsAspect注解切面
 *
 * @author hujiabin wrote in 2024/1/20 17:09
 */
@Aspect
@Component
@Slf4j
public class ExecutionTimeStatisticsAspect {

    @Around("@annotation(executionTimeStatistics)")
    public Object logExecutionTimeStatistics(ProceedingJoinPoint joinPoint, ExecutionTimeStatistics executionTimeStatistics) throws Throwable {
        StopWatch sw = null;
        String taskName = joinPoint.getSignature().toString();
        try {
            String stopWatchId = executionTimeStatistics.stopWatchId();
            if ("".equals(stopWatchId)) {
                sw = new StopWatch(taskName);
            } else {
                Map<String, StopWatch> allStopWatch = StopWatchContext.getAllStopWatch();
                if (allStopWatch.containsKey(stopWatchId)) {
                    sw = allStopWatch.get(stopWatchId);
                } else {
                    sw = new StopWatch(stopWatchId);
                    StopWatchContext.getAllStopWatch().put(stopWatchId, sw);
                }
                taskName = executionTimeStatistics.taskName();
                taskName = "".equals(taskName) ? joinPoint.getSignature().toString() : taskName;
            }
            log.info("{}：开始执行", taskName);
            sw.start(taskName);
            return joinPoint.proceed();
        } finally {
            if (sw != null) {
                sw.stop();
            }
            log.info("{}：执行结束", taskName);
        }
    }
}
